#include "MySQLite.h"
#include <time.h>

#include <iostream>
#include <thread>


/// Get path to this example's directory (including the final separator '/' or '\')
static inline std::string getExamplePath()
{
    std::string filePath(__FILE__);
    // std::cout << filePath << std::endl;
    return filePath.substr( 0, filePath.length() - std::string("main.cpp").length());
}

/// Example Database
static const std::string filename_example_db3   = getExamplePath() + "testDB.db";

// 回调函数--有参数json类型
void print( json& table)
{
    std::cout << "print in Callback " << std::endl;
    int length = table.size();  // 获取返回结果有几行
    for (int i = 0; i < length; ++i) {
         std::string rowString =  std::to_string(i + 1);  // 行号
        std::cout << "row" << rowString << ": ";
        for (auto& elem: table[rowString]) {
             std::cout << elem << " ";
        }
        std::cout << std::endl;
    }   
}

// void testInsert( MySQLite& msqlt, int id)
void testInsert( MySQLite& msqlt)
{
    // 表名 列名 数据
    const std::string tableName = "COMPANY";
    // std::vector<std::string> colName = {"ID", "NAME", "AGE", "ADDRESS", "SALARY"};
    // std::vector<std::string> colName;
    std::vector<std::string> colName = {"ID", "NAME", "AGE"};
    json values = json::array({1000000, "Mark", 25});
    msqlt.insert(tableName, colName, values);
}

void testSelect(  MySQLite& msqlt)
{
    // 表名  列名  条件
    const std::string tableName = "COMPANY";
    // 1; 情况一
    // std::vector<std::string> colName = {"ID", "NAME", "AGE", "ADDRESS", "SALARY"};
    // 2、std::vector<std::string> colName = {"*"}; // 情况二
     std::vector<std::string> colName = {"*"};
      const std::string condition = "ID = 3 " ;
     // const std::string condition = "";

    //json table = msqlt.queryWrapper(tableName, colName, condition, nullptr);  
    // 查询到结果后要做的事情以回调函数注册进去，程序这里不希望阻塞，
    msqlt.queryWrapper(tableName, colName, condition, print);  // print 是有参数的

    // std::cout << table["NAME"] << std::endl;
   
    
    //std::cout << std::endl;
}

void testDelete(MySQLite& msqlt)
{
    // 表名  条件
    const std::string tableName = "COMPANY";
    const std::string condition = "ID > 100000" ;
    msqlt.deleteValue(tableName, condition);
}


#if 0
// 测试两个线程写，一个线程读
#define COUNT1 1000000
#define COUNT2 200000

void testInsert( MySQLite& msqlt, int id)
// void testInsert( MySQLite& msqlt)
{
    // 表名 列名 数据
    const std::string tableName = "COMPANY";
    // std::vector<std::string> colName = {"ID", "NAME", "AGE", "ADDRESS", "SALARY"};
    std::vector<std::string> colName;
    
    json values = json::array({ id, "Mark", 25, "Rich-Mond", 65000.00});
    msqlt.insert(tableName, colName, values);
}

void test3W( MySQLite& msqlt)
{
    for (int id = 6; id < COUNT1; ++id) {
        testInsert(msqlt, id);
    }
}


void test4W( MySQLite& msqlt)
{
     for (int id = COUNT1; id < COUNT2; ++id) {
        testInsert(msqlt, id);
    }
}

void testR(MySQLite& msqlt)
{
    for (int id = 1; id < COUNT2; ++id) {
        testSelect(msqlt, id);
    }
}


// 测试表中10万条数据， 随机查找10万次的时间
void test100m_S( MySQLite& msqlt) 
{
    
      //2  表名  列名  条件
    const std::string tableName = "COMPANY";
    std::vector<std::string> colName = {"*"};
    // 执行10万次查询
    for (int i = 0; i < COUNT1; ++i) {
        // 1、生成一个随机数
        ::srand((unsigned)time(NULL));
        int id = rand() % 1000000;
         const std::string condition = "ID = " + std::to_string(id) ;
        json table = msqlt.query(tableName, colName, condition);
    }
    
    /*for (auto& elem : table["1"]) {
        std::cout << elem << " ";
    }
     putchar('\n');*/
}

#endif

int main()
{
    // std::cout << filename_example_db3 << std::endl;
    const std::string DbName = filename_example_db3 ;

    MySQLite* pmsqlt = MySQLite::getInstance(DbName);   // 创建对象
    // MySQLite msqlt(DbName);
    // MySQLite msqlt2(DbName); // 第二个数据库连接对象

    // 1、查找
     testSelect((*pmsqlt));

    // 2、插入 insert
    // testInsert(*pmsqlt);

    // 3、删除 delete
     // testDelete(*pmsqlt);
    time_t begin = ::time(nullptr);

     //test100m_S(*pmsqlt);

    time_t end = ::time(nullptr);
    double time_diff = difftime(end, begin);
    std::cout << "time_diff: " << time_diff << "s" << std::endl;

    // test3W(*pmsqlt);
     
#if 0
    
    // 测试线程 --传入了两个不同的对象
    // int id = 8;
    std::thread write1(test3W, std::ref(*msqlt));  
    // int id2 = 9;
    std::thread write2(test4W, std::ref(msqlt)); 

    std::thread read(testR, std::ref(msqlt));
    write1.join();
    write2.join();
    read.join();
 #endif   
    return 0;
}